package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"xindl/deployer/internal/config"
	"xindl/deployer/internal/deployer"
	"xindl/deployer/pkg/logger"
)

var (
	// 版本信息，通过编译时注入
	Version   = "0.1.0"
	BuildTime = "unknown"
	GitCommit = "unknown"

	// 命令行参数
	port           = flag.Int("port", 8080, "指定服务端口")
	env            = flag.String("env", "prod", "指定运行环境 [prod/test]")
	mirror         = flag.String("mirror", "docker.io/library", "指定Docker镜像源")
	replicas       = flag.Int("replicas", 2, "指定服务副本数")
	jdk            = flag.String("jdk", "8", "指定JDK版本 [8/11]")
	service        = flag.String("service", "", "指定服务名称")
	repo           = flag.String("repo", "", "指定代码仓库地址")
	branch         = flag.String("branch", "", "指定代码分支")
	builder        = flag.String("builder", "maven", "指定构建工具 [maven/gradle]")
	cpuLimit       = flag.String("cpu-limit", "1", "指定CPU上限")
	cpuRequest     = flag.String("cpu-request", "0.5", "指定CPU预留")
	memoryLimit    = flag.String("memory-limit", "2048M", "指定内存上限")
	memoryRequest  = flag.String("memory-request", "1024M", "指定内存预留")
	healthCheck    = flag.Bool("health-check", true, "启用健康检查")
	healthEndpoint = flag.String("health-endpoint", "/check", "健康检查路径")
	debug          = flag.Bool("debug", false, "开启调试模式")
	version        = flag.Bool("version", false, "显示版本信息")
)

func main() {
	// 解析命令行参数
	flag.Parse()

	// 初始化日志记录器
	log := logger.New(*debug)
	defer log.Close()

	// 显示版本信息
	if *version {
		log.Info("Deployer %s", Version)
		log.Info("构建时间: %s", BuildTime)
		log.Info("Git提交: %s", GitCommit)
		os.Exit(0)
	}

	// 显示帮助信息
	if len(os.Args) == 1 {
		fmt.Println("Deployer - 基于Docker Swarm的Java应用自动化部署工具")
		fmt.Println("\n用法: deployer [选项]")
		fmt.Println("\n选项:")
		flag.PrintDefaults()
		os.Exit(0)
	}

	// 验证必填参数
	if *service == "" {
		log.Error("必须指定服务名称 (--service)")
		os.Exit(1)
	}
	if *repo == "" {
		log.Error("必须指定代码仓库地址 (--repo)")
		os.Exit(1)
	}
	if *branch == "" {
		log.Error("必须指定代码分支 (--branch)")
		os.Exit(1)
	}

	// 输出配置信息
	log.Info("当前配置:")
	log.Info("├─ 服务名称: %s", *service)
	log.Info("├─ 代码仓库: %s", *repo)
	log.Info("├─ 代码分支: %s", *branch)
	log.Info("├─ 运行环境: %s", *env)
	log.Info("├─ 服务端口: %d", *port)
	log.Info("├─ 副本数量: %d", *replicas)
	log.Info("├─ JDK版本: %s", *jdk)
	log.Info("├─ 构建工具: %s", *builder)
	log.Info("├─ 镜像源: %s", *mirror)
	log.Info("├─ CPU限制: %s", *cpuLimit)
	log.Info("├─ CPU预留: %s", *cpuRequest)
	log.Info("├─ 内存限制: %s", *memoryLimit)
	log.Info("├─ 内存预留: %s", *memoryRequest)
	log.Info("├─ 健康检查: %v", *healthCheck)
	if *healthCheck {
		log.Info("└─ 健康检查路径: %s", *healthEndpoint)
	}

	// 创建上下文
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 处理信号
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		sig := <-sigChan
		log.Warn("收到信号: %v", sig)
		cancel()
	}()

	// 执行环境检查
	checker := config.NewEnvChecker(log)
	if err := checker.CheckAll(ctx); err != nil {
		log.Error("环境检查失败: %v", err)
		os.Exit(1)
	}
	log.Info("环境检查通过")

	// 创建部署配置
	deployConfig := &deployer.DeployConfig{
		ServiceName: *service,
		Port:        *port,
		Env:         *env,
		Replicas:    *replicas,

		Repository: *repo,
		Branch:     *branch,

		BuildTool:  *builder,
		JDKVersion: *jdk,
		SkipTests:  true,

		DockerMirror: *mirror,

		CPULimit:      *cpuLimit,
		CPURequest:    *cpuRequest,
		MemoryLimit:   *memoryLimit,
		MemoryRequest: *memoryRequest,

		HealthCheck:    *healthCheck,
		HealthEndpoint: *healthEndpoint,

		Debug: *debug,
	}

	// 创建部署协调器
	coordinator := deployer.NewCoordinator(deployConfig)

	// 执行部署
	log.Info("开始部署...")
	if err := coordinator.Deploy(ctx); err != nil {
		log.Error("部署失败: %v", err)
		os.Exit(1)
	}

	log.Info("部署完成")
}
